
package com.zbkj.crmeb.merchant.admin.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.crmeb.core.annotation.UnitConvertUtil;
import com.crmeb.core.config.MybatisPlusConfig;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.crmeb.core.utils.TableNameUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taobao.pac.sdk.cp.dataobject.request.MODUAN_ORDER_CREATE.request;
import com.utils.*;
import com.utils.dto.StoreProductQueryDto;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.category.model.Category;
import com.zbkj.crmeb.category.service.CategoryService;
import com.zbkj.crmeb.chant.model.*;
import com.zbkj.crmeb.chant.service.*;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.enums.plat.PlatPushStatusEnums;
import com.zbkj.crmeb.export.vo.ProductExcelVo;
import com.zbkj.crmeb.front.request.IndexStoreProductSearchRequest;
import com.zbkj.crmeb.front.request.ProductRequest;
import com.zbkj.crmeb.front.vo.RatioVo;
import com.zbkj.crmeb.marketing.dto.CouponProductRangeDTO;
import com.zbkj.crmeb.marketing.model.StoreCouponUser;
import com.zbkj.crmeb.member.enums.EquityTypeEnum;
import com.zbkj.crmeb.member.model.MerchantMemberBenefits;
import com.zbkj.crmeb.member.model.StoreProductDiscount;
import com.zbkj.crmeb.member.service.IMerchantMemberBenefitsService;
import com.zbkj.crmeb.member.service.IStoreProductDiscountService;
import com.zbkj.crmeb.merchant.admin.service.MerStoreProductService;
import com.zbkj.crmeb.merchant.admin.service.StoreProductStockService;
import com.zbkj.crmeb.merchant.api.service.FrontCouponUserService;
import com.zbkj.crmeb.merchant.api.service.MerStoreCartService;
import com.zbkj.crmeb.plat.enums.MerPlatEnums;
import com.zbkj.crmeb.store.dao.StoreProductAttrValueDao;
import com.zbkj.crmeb.store.dao.StoreProductDao;
import com.zbkj.crmeb.store.dao.StoreProductNormDao;
import com.zbkj.crmeb.store.dto.product.StoreProductQueryDTO;
import com.zbkj.crmeb.store.intercept.RateLimiter;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.request.*;
import com.zbkj.crmeb.store.response.*;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.utilService.OrderUtils;
import com.zbkj.crmeb.system.model.SystemConfig;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.service.UserService;

/**
 * @author Mr.Zhang
 * @description StoreProductServiceImpl 接口实现
 * @date 2020-05-27
 */
@Slf4j
@Service
public class StoreProductStockServiceImpl implements StoreProductStockService {
    @Autowired
    PriceUtil priceUtil;
    @Resource
    private StoreProductService storeProductService;
    @Resource
    private StoreProductDao storeProductDAO;
    @Resource
    private StoreProductNormDao storeProductNormDAO;
    @Resource
    private StoreProductAttrValueDao storeProductAttrValueDAO;
    @Autowired
    private StoreProductAttrService attrService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private StoreProductCateService storeProductCateService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private StoreProductDescriptionService storeProductDescriptionService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private StoreProductRelationService storeProductRelationService;
    @Autowired
    private SystemAttachmentService systemAttachmentService;
    @Autowired
    private StoreProductAttrResultService storeProductAttrResultService;
    @Autowired
    private StoreProductCouponService storeProductCouponService;
    @Autowired
    private StoreBrandService storeBrandService;
    @Autowired
    private MarkupRateService markupRateService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private ProductUtil productUtil;
    @Resource
    private StoreProductMerService storeProductMerService;
    @Autowired
    private ICategoryMatchService categoryMatchService;
    @Autowired
    private StoreZoneProductService storeZoneProductService;
    @Autowired
    private StoreZoneService storeZoneService;
    @Autowired
    private SystemAdminService systesmAdminService;
    @Autowired
    private FrontCouponUserService frontCouponUserService;
    @Autowired
    private StoreProductNormDescriptionService storeProductNormDescriptionService;
    @Autowired
    private ProductConvertUtil productConvertUtil;
    @Autowired
    private IStoreProductDiscountService storeProductDiscountService;
    @Autowired
    private IMerchantMemberBenefitsService merchantMemberBenefitsService;
    @Autowired
    private ChannelMemberLevelService channelMemberLevelService;
    @Autowired
    private UserService userService;

    @Autowired
    private UserCommissionService userCommissionService;
    @Autowired
    private StoreProductDraftService storeProductDraftService;
    @Autowired
    private StoreProductAttrValueDraftService storeProductAttrValueDraftService;
    @Autowired
    private StoreProductUploadService storeProductUploadService;
    @Resource
    private ChannelDiscountService channelDiscountService;
    @Resource
    private ChannelDiscountGoodsService channelDiscountGoodsService;
    @Autowired
    private MerStoreCartService merStoreCartService;
    @Autowired
    private OrderUtils orderUtils;
    @Resource
    private RelationService relationService;
    @Autowired
    StoreProductValueMerService storeProductValueMerService;
    @Autowired
    private ChannelFreeShippingActivityService channelFreeShippingActivityService;
    @Autowired
    private StoreProductGroupActivityService storeProductGroupActivityService;
    @Autowired
    private ChannelGroupBookingService channelGroupBookingService;


    /**
     * 对于拼团活动更新库存量(购买，退款，取消)
     * @return
     */
    public boolean updateStock(Integer productId, String attrValueId, Integer num, Integer type, Integer activityGroupId){
        log.info("updateStock：{}，{}，{},{},{}",productId, attrValueId, num, type, activityGroupId);

        if(null == activityGroupId || 0 == activityGroupId
                || null == productId || 0 == productId
                || null == attrValueId
                || null == num || 0 == num){
            return false;
        }
        ChannelGroupBooking channelGroupBooking = channelGroupBookingService.getById(activityGroupId);
        log.info("channelGroupBooking:{}",JSONObject.toJSONString(channelGroupBooking));

        // 团长id
        if(null == channelGroupBooking) {
            return false;
        }
        // 获取拼团库存量
        StoreProductGroupActivity groupActivity = storeProductGroupActivityService.getOne(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                .eq(StoreProductGroupActivity::getProductId, productId)
                .eq(StoreProductGroupActivity::getSourceSkuId, attrValueId)
                .eq(StoreProductGroupActivity::getActivityId, activityGroupId)
                .last("LIMIT 1"));
        log.info("获取拼团库存量：{}",JSON.toJSONString(groupActivity));

        if(null == groupActivity){
            throw new CrmebException("未获取到拼团商品！");
        }

        // 拼团库存量扣减
        Integer stock1 = groupActivity.getStock() == null ? 0 : groupActivity.getStock();
        stock1 = stock1 - num;
        if(stock1 < 0){
            throw new CrmebException(String.format("拼团商品：%s的库存量不足！", groupActivity.getSourceSkuId()));
        }
        log.info("拼团库存量扣减：{}",stock1);

        LambdaUpdateWrapper<StoreProductGroupActivity> updateWrapper = new LambdaUpdateWrapper();
        updateWrapper.eq(StoreProductGroupActivity::getId, groupActivity.getId());
        updateWrapper.set(StoreProductGroupActivity::getStock, stock1);
        storeProductGroupActivityService.update(updateWrapper);

        // 获取商品库存量
        StoreProductAttrValue attrValue = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .eq(StoreProductAttrValue::getProductId, productId)
                .eq(StoreProductAttrValue::getSourceSkuId, attrValueId)
                .last("LIMIT 1")
        );
        log.info("获取商品库存量：{}",JSON.toJSONString(attrValue));

        if(null == attrValue){
            throw new CrmebException("未查找到商品！");
        }
        // 商品的拼团锁定库存量扣减
        Integer productGroupStock = attrValue.getGroupStock() == null ? 0 : attrValue.getGroupStock();
        productGroupStock = productGroupStock - num;
        if(productGroupStock < 0){
            productGroupStock = 0;
        }

        log.info("商品的拼团锁定库存量扣减：{},{}",attrValue.getGroupStock(), productGroupStock);

        LambdaUpdateWrapper<StoreProductAttrValue> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(StoreProductAttrValue::getProductId, productId);
        lambdaUpdateWrapper.eq(StoreProductAttrValue::getSourceSkuId, attrValueId);
        lambdaUpdateWrapper.eq(StoreProductAttrValue::getType, type);

        lambdaUpdateWrapper.set(StoreProductAttrValue::getGroupStock, productGroupStock);
        return storeProductAttrValueService.update(lambdaUpdateWrapper);

    }

    /**
     * 退款时，归还商品锁定的库存
     *
     * @param storeOrderInfo
     */
    @Override
    public boolean refundStock(StoreOrderInfo storeOrderInfo) {
        log.info("refundStock：{}",JSON.toJSONString(storeOrderInfo));

        // 真拼团活动id
        Integer activityGroupId = storeOrderInfo.getActivityGroupId();
        //
        ChannelGroupBooking channelGroupBooking = channelGroupBookingService.getById(activityGroupId);
        log.info("refundStock channelGroupBooking:{}",JSONObject.toJSONString(channelGroupBooking));

        // 团长id
        if(null == channelGroupBooking) {
            log.info("拼团活动不存在:{}",activityGroupId);
            return false;
        }
        StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
        log.info("refundStock storeCartResponse：{}",JSON.toJSONString(storeCartResponse));

        // 拼团表的拼团库存

        // 获取拼团库存量
        StoreProductGroupActivity groupActivity = storeProductGroupActivityService.getOne(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                .eq(StoreProductGroupActivity::getProductId, storeOrderInfo.getProductId())
                .eq(StoreProductGroupActivity::getSourceSkuId, storeCartResponse.getProductInfo().getAttrInfo().getSourceSkuId())
                .eq(StoreProductGroupActivity::getActivityId, activityGroupId)
                .last("LIMIT 1"));
        log.info("refundStock groupActivity：{}",JSON.toJSONString(groupActivity));

        if(null == groupActivity){
            log.info("未获取到拼团商品:{}",activityGroupId);
            return false;
        }

        // 拼团库存量返还
        Integer stock1 = groupActivity.getStock() == null ? 0 : groupActivity.getStock();
        stock1 = stock1 + storeCartResponse.getCartNum();
        if(stock1 < 0){
            stock1 = 0;
        }
        log.info("refundStock 拼团库存量返还：{}",stock1);

        LambdaUpdateWrapper<StoreProductGroupActivity> updateWrapper = new LambdaUpdateWrapper();
        updateWrapper.eq(StoreProductGroupActivity::getId, groupActivity.getId());
        updateWrapper.set(StoreProductGroupActivity::getStock, stock1);
        storeProductGroupActivityService.update(updateWrapper);


        // 商品的拼团库存

        //buyer的商品 查询attrvalue
        if(ProductTypeEnum.BUYER.getCode() == storeCartResponse.getProductInfo().getIsEurope()){
            StoreProductAttrValue apAttrValuePram = new StoreProductAttrValue();
            apAttrValuePram.setSourceSkuId(storeCartResponse.getProductInfo().getAttrInfo().getSourceSkuId());
            apAttrValuePram.setProductId(storeOrderInfo.getProductId());
            apAttrValuePram.setType(0);
            LambdaQueryWrapper<StoreProductAttrValue> lqw = new LambdaQueryWrapper<>();
            lqw.setEntity(apAttrValuePram);
            StoreProductAttrValue attrValue = storeProductAttrValueDAO.selectOne(lqw);
            if(null != attrValue){
                // 商品的拼团锁定库存量返还
                Integer productGroupStock = attrValue.getGroupStock() == null ? 0 : attrValue.getGroupStock();
                productGroupStock = productGroupStock + storeCartResponse.getCartNum();
                if(productGroupStock < 0){
                    productGroupStock = 0;
                }
                log.info("refundStock 商品的拼团锁定库存量返还1：{}",productGroupStock);

                LambdaUpdateWrapper<StoreProductAttrValue> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(StoreProductAttrValue::getProductId,storeOrderInfo.getProductId());
                lambdaUpdateWrapper.eq(StoreProductAttrValue::getSourceSkuId, attrValue.getSourceSkuId());
                lambdaUpdateWrapper.set(StoreProductAttrValue::getGroupStock, productGroupStock);
                storeProductAttrValueService.update(lambdaUpdateWrapper);

            }
        }else{
            StoreProductAttrValue apAttrValuePram = new StoreProductAttrValue();
            apAttrValuePram.setProductId(storeOrderInfo.getProductId());
            apAttrValuePram.setBarCode(storeCartResponse.getProductInfo().getAttrInfo().getBarCode());
            apAttrValuePram.setSuk(storeCartResponse.getProductInfo().getAttrInfo().getSuk());
            apAttrValuePram.setSourceSkuId(storeCartResponse.getProductInfo().getAttrInfo().getSourceSkuId());
            LambdaQueryWrapper<StoreProductAttrValue> lqw = new LambdaQueryWrapper<>();
            lqw.setEntity(apAttrValuePram);
            StoreProductAttrValue attrValue = storeProductAttrValueDAO.selectOne(lqw);
            if(null != attrValue){
                // 商品的拼团锁定库存量返还
                Integer productGroupStock = attrValue.getGroupStock() == null ? 0 : attrValue.getGroupStock();
                productGroupStock = productGroupStock + storeCartResponse.getCartNum();
                if(productGroupStock < 0){
                    productGroupStock = 0;
                }
                log.info("refundStock 商品的拼团锁定库存量返还2：{}",productGroupStock);

                LambdaUpdateWrapper<StoreProductAttrValue> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(StoreProductAttrValue::getProductId, attrValue.getProductId());
                lambdaUpdateWrapper.eq(StoreProductAttrValue::getBarCode, attrValue.getBarCode());
                lambdaUpdateWrapper.eq(StoreProductAttrValue::getSuk, attrValue.getSuk());
                lambdaUpdateWrapper.set(StoreProductAttrValue::getGroupStock, productGroupStock);
                storeProductAttrValueService.update(lambdaUpdateWrapper);

            }
        }
        return true;
    }

    /**
     * 归还拼团锁定的库存量
     */
    @Override
    public void returnStockForActivityFinish(ChannelGroupBooking groupBooking, List<Integer> activityIds, String logID) {
        log.info("returnStockForActivityFinish:[{}], {}",logID,JSON.toJSONString(groupBooking));

        if(null == groupBooking){
            return;
        }
        String groupId = groupBooking.getGroupId();
        List<StoreProductGroupActivity> list = new ArrayList<>();
        if(StringUtils.isNotBlank(groupId)){
            list = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .eq(StoreProductGroupActivity::getGroupId, groupId));
        }else if (CollectionUtils.isNotEmpty(activityIds)){
            list = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .in(StoreProductGroupActivity::getActivityId, activityIds)
                    .isNull(StoreProductGroupActivity::getGroupId));
        }
        if(CollectionUtils.isEmpty(list)){
            log.info("归还拼团锁定的库存量异常，怎么可以没有拼团原数据！");
            return;
        }
        List<Integer> productIds = list.stream().map(StoreProductGroupActivity::getProductId).distinct().collect(Collectors.toList());
        // 获取商品规格
        List<StoreProductAttrValue> attrValueList = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .in(StoreProductAttrValue::getProductId, productIds)
        );
        if (CollectionUtils.isEmpty(attrValueList)) {
            log.info("拼团原商品对应的商品为空，不用返还库存");
            return;
        }
        // map
        Map<String, StoreProductAttrValue> attrValueMap = attrValueList.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, e -> e, (v1, v2) -> v2));

        for(StoreProductGroupActivity activity : list){
            Integer stock = activity.getStock();
            if (null == stock || 0 == stock) {
                continue;
            }
            String sourceSkuId = activity.getSourceSkuId();
            if(null == sourceSkuId){
                log.info("商品规格id为空！");
                continue;
            }
            StoreProductAttrValue attrValue = attrValueMap.get(sourceSkuId);
            if(null == attrValue){
                continue;
            }
            Integer newStock = attrValue.getStock() == null ? 0 : attrValue.getStock();
            Integer productGroupStock = attrValue.getGroupStock() == null ? 0 : attrValue.getGroupStock();
            newStock += stock;
            productGroupStock -= stock;
            if(productGroupStock < 0){
                productGroupStock = 0;
            }

            // 归还库存
            LambdaUpdateWrapper<StoreProductAttrValue> updateWrapper = new LambdaUpdateWrapper();
            updateWrapper.eq(StoreProductAttrValue::getId, attrValue.getId());
            updateWrapper.set(StoreProductAttrValue::getStock, newStock);
            updateWrapper.set(StoreProductAttrValue::getGroupStock, productGroupStock);
            storeProductAttrValueService.update(updateWrapper);

            activity.setStock(0);

        }
        storeProductGroupActivityService.updateBatchById(list);

        // 设置此次活动已归还库存
        LambdaUpdateWrapper<ChannelGroupBooking> updateWrapper = new LambdaUpdateWrapper();
        updateWrapper.eq(ChannelGroupBooking::getId, groupBooking.getId());
        updateWrapper.set(ChannelGroupBooking::getReturnStock, SwitchEnum.OPEN.getCode());
        channelGroupBookingService.update(updateWrapper);

    }

    /**
     * 设置拼团价和拼团库存
     *
     * @param groupId
     * @param storeProductAttrValues
     */
    @Override
    public void calcStockAndPrice(String groupId, Integer activityId, List<StoreProductAttrValue> storeProductAttrValues) {
        if(StringUtils.isEmpty(groupId) && (null == activityId || 0 == activityId)){
            return;
        }
        Map<String, StoreProductAttrValue> storeProductAttrValueMap = storeProductAttrValues.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, e -> e, (v1, v2) -> v2));

        List<StoreProductGroupActivity> productGroupActivityList = new ArrayList<>();
        if(StringUtils.isNotEmpty(groupId)) {
            productGroupActivityList = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .eq(StoreProductGroupActivity::getGroupId, groupId));
        }else if(null != activityId && 0 != activityId){
            productGroupActivityList = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .eq(StoreProductGroupActivity::getActivityId, activityId));
        }
        if(CollectionUtils.isEmpty(productGroupActivityList)){
            return;
        }
        for(StoreProductGroupActivity activity : productGroupActivityList){
            if(activity == null || activity.getSourceSkuId() == null){
                continue;
            }
            StoreProductAttrValue attrValue = storeProductAttrValueMap.get(activity.getSourceSkuId());
            if(attrValue == null){
                continue;
            }
            if(activity.getStock() != null){
                attrValue.setStock(activity.getStock());
                attrValue.setGroupStock(activity.getStock());
            }
//            if(activity.getPackagePrice() != null){
//                attrValue.setCost(activity.getPackagePrice());
//            }

        }

    }

    @Override
    public String getGroupIdByProductIdAndLeaderId(String leaderId, List<Integer> cartIds ,Integer merId,boolean isNew) {
        log.info("getGroupIdByProductIdAndLeaderId 入口：{}，{}，{}，{}" , leaderId, JSONObject.toJSONString(cartIds), merId, isNew);
        if(StringUtils.isEmpty(leaderId) || "0".equals(leaderId)){
            return null;
        }
        User currentUserInfo = userService.getInfo();
        ChannelMerchant channelMerchant = channelMerchantService.getById(merId);
        List<StoreCartResponse> storeCartResponse = new ArrayList<>();
        // isNew=false 从购物车获取 isNew=true 从缓存中获取=再次下单
        if (isNew) {
            storeCartResponse = orderUtils.getCacheOrderAgain(cartIds.get(0) + ""); // todo 按照存储规格这里应该只会有一个值

        } else {
            storeCartResponse = merStoreCartService.getListByUserIdAndCartIds(currentUserInfo.getUid(), cartIds, channelMerchant, null);
        }
        log.info("getGroupIdByProductIdAndLeaderId storeCartResponse：{}，{}" , JSONObject.toJSONString(storeCartResponse));

        if (storeCartResponse.get(0).getPickingId() == 0) {
            StoreCartResponse cartResponse = storeCartResponse.get(0);
            Integer productId = cartResponse.getProductId();
            //该商户下进行中的拼团活动
            Integer leaderId2;
            try {
                leaderId2 = Integer.valueOf(leaderId);
            }catch (Exception e){
                log.error("数据转换错误 jsonStr:{}", leaderId);
                leaderId2 = 0;
            }
            List<Integer> groupActivityIds = channelGroupBookingService.getInProgressActivityIdsAndLeaderId(channelMerchant.getId(), leaderId2);
            log.info("getGroupIdByProductIdAndLeaderId groupActivityIds：{}，{}" , JSONObject.toJSONString(groupActivityIds));

            //商户下没有进行中的拼团活动，不设置商品拼团价，直接返回
            if (CollectionUtils.isEmpty(groupActivityIds)) {
                return null;
            }
            // 商品sku对应的拼团价格
            StoreProductGroupActivity storeProductGroupActivity = storeProductGroupActivityService.getByIdAndActivityIdList(groupActivityIds, productId);
            log.info("getGroupIdByProductIdAndLeaderId storeProductGroupActivity：{}，{}" , JSONObject.toJSONString(storeProductGroupActivity));

            //没有该商品的活动信息
            if (null == storeProductGroupActivity) {
                return null;
            }else{
                return storeProductGroupActivity.getGroupId();
            }

        }
        return null;

    }

    @Override
    public String getGroupIdByProductIdAndLeaderIdV2(String leaderId, Integer productId, Integer merId) {
        log.info("getGroupIdByProductIdAndLeaderIdV2 入口：{}，{}，{}" , leaderId, productId, merId);
        if(StringUtils.isEmpty(leaderId) || "0".equals(leaderId)){
            return null;
        }
        ChannelMerchant channelMerchant = channelMerchantService.getById(merId);

        //该商户下进行中的拼团活动
        Integer leaderId2;
        try {
            leaderId2 = Integer.valueOf(leaderId);
        }catch (Exception e){
            log.error("数据转换错误 jsonStr:{}", leaderId);
            leaderId2 = 0;
        }
        List<Integer> groupActivityIds = channelGroupBookingService.getInProgressActivityIdsAndLeaderId(channelMerchant.getId(), leaderId2);
        log.info("getGroupIdByProductIdAndLeaderIdV2 groupActivityIds：{}，{}" , JSONObject.toJSONString(groupActivityIds));

        //商户下没有进行中的拼团活动，不设置商品拼团价，直接返回
        if (CollectionUtils.isEmpty(groupActivityIds)) {
            return null;
        }
        // 商品sku对应的拼团价格
        StoreProductGroupActivity storeProductGroupActivity = storeProductGroupActivityService.getByIdAndActivityIdList(groupActivityIds, productId);
        log.info("getGroupIdByProductIdAndLeaderIdV2 storeProductGroupActivity：{}，{}" , JSONObject.toJSONString(storeProductGroupActivity));

        //没有该商品的活动信息
        if (null == storeProductGroupActivity) {
            return null;
        }else{
            return storeProductGroupActivity.getGroupId();
        }


    }

    /**
     * 后台显示库存量
     * @return
     */
    public boolean showStock(StoreProductAttrValue attrValue){

        // 将剩余可用库存量加上拼团锁定库存量，赋值给总库存量
        if (attrValue == null || attrValue.getGroupStock() == null || attrValue.getGroupStock() <= 0) {
            return false;
        }
        // 将剩余可用库存量加上拼团锁定库存量
        Integer stock = attrValue.getStock() == null ? 0:attrValue.getStock();
        attrValue.setStock(stock + attrValue.getGroupStock());
        // 返回给后台总库存量
        return true;

    }

    /**
     * 后台显示库存量
     * @return
     */
    public boolean showStockBatch(List<StoreProductAttrValue> attrValueList){
        if(CollectionUtils.isEmpty(attrValueList)){
            return false;
        }
        for(StoreProductAttrValue attrValue : attrValueList){
            if (attrValue != null && attrValue.getGroupStock() != null && attrValue.getGroupStock() > 0) {
                Integer stock01 = attrValue.getStock();
                attrValue.setUseStock(stock01);
                // 将剩余可用库存量加上拼团锁定库存量
                attrValue.setStock(stock01 + attrValue.getGroupStock());
            }
        }
        // 返回给后台总库存量
        return true;
    }

    /**
     * 供应商修改库存量
     * @return
     */
    public boolean editStock(StoreProductAttrValue newAttrValue, StoreProductAttrValue oldAttrValue){
        log.info("供应商修改库存量 editStock入口 ：{}，{}",JSON.toJSONString(newAttrValue),JSON.toJSONString(oldAttrValue));

        if (null == oldAttrValue || null == newAttrValue) {
            return false;
        }
        Integer groupStock = oldAttrValue.getGroupStock();
        if(null != groupStock && groupStock > 0){
            Integer stock = newAttrValue.getStock() == null ? 0 : newAttrValue.getStock();
            if(stock - groupStock < 0){
                throw new CrmebException(String.format("拼团锁定库存量为%s，输入的新库存量不能低于该值", groupStock));
            }
            newAttrValue.setStock(stock - groupStock);
            newAttrValue.setGroupStock(groupStock);
            newAttrValue.setTotalStock(stock);
        }
        log.info("供应商修改库存量 editStock ：{}",JSON.toJSONString(newAttrValue));

        return true;
    }

    /**
     * 校验商品的拼团库存量是否超过商品库存量
     *
     * @param activityIds
     */
    @Override
    public void checkNewStock(ChannelGroupBookingRequest request, List<Integer> activityIds) {
        if (CollectionUtils.isEmpty(activityIds)){
            return ;
        }
        String groupId = request.getGroupId();
        Integer productId = request.getProductId();
        List<StoreProductGroupActivity> list = new ArrayList<>();
        if(StringUtils.isNotBlank(groupId)){
            list = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .eq(StoreProductGroupActivity::getProductId, productId)
                    .eq(StoreProductGroupActivity::getGroupId, groupId));
        }else {
            list = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .eq(StoreProductGroupActivity::getProductId, productId)
                    .in(StoreProductGroupActivity::getActivityId, activityIds)
                    .isNull(StoreProductGroupActivity::getGroupId));
        }
        if(CollectionUtils.isEmpty(list)){
            throw new CrmebException("程序异常，修改了商品，可是进入了未修改商品的库存量校验！");
        }
        // Map
        Map<String, Integer> skuStockMap = list.stream().collect(Collectors.toMap(StoreProductGroupActivity::getSourceSkuId, StoreProductGroupActivity::getStock));

        // 获取商品规格
        List<StoreProductAttrValue> attrValueList = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .eq(StoreProductAttrValue::getProductId, productId)
        );
        if (CollectionUtils.isEmpty(attrValueList)) {
            throw new CrmebException("拼团对应的商品为空，数据异常");
        }
        // map
        Map<String, StoreProductAttrValue> attrValueMap = attrValueList.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, e -> e, (v1, v2) -> v2));

        //拼团人数与拼团价对应关系
        List<ChannelGroupBookingRequest.StoreProductGroupActivityRequest> storeProductGroupActivities = request.getStoreProductGroupActivities();
        for (ChannelGroupBookingRequest.StoreProductGroupActivityRequest activityRequest : storeProductGroupActivities) {
            for (ChannelGroupBookingRequest.StoreProductGroupActivityRequest.StoreProductGroupPriceRequest priceRequest : activityRequest.getSkuPrices()) {
                String sourceSkuId = priceRequest.getSourceSkuId();
                Integer newStock = priceRequest.getStock();
                Integer oldStock = skuStockMap.get(sourceSkuId);

//                if(null == newStock || newStock == 0){
//                    throw new CrmebException("拼团库存量不能为空！");
//                }
                if(null == oldStock || oldStock == 0){
                    oldStock = 0;
                }
                if(null == sourceSkuId){
                    throw new CrmebException("商品规格不能为空！");
                }
                // 获取商品的库存量
                // 商品规格
                StoreProductAttrValue attrValue = attrValueMap.get(sourceSkuId);
                if(null == attrValue){
                    throw new CrmebException("商品规格为空，数值异常！");
                }
                // 商品库存量
                if(attrValue.getStock() == null){
                    attrValue.setStock(0);
                }
                if (attrValue.getStock() + oldStock < newStock) {
                    log.info("库存量：{}，{}，{}",attrValue.getStock(), oldStock, newStock);
                    throw new CrmebException("商品可用库存量不足，请修改参加拼团的库存量！");
                }

                // 锁库存
                Integer stock = attrValue.getStock() + oldStock - newStock;
                Integer productGroupStock = attrValue.getGroupStock() == null ? 0 : attrValue.getGroupStock();
                productGroupStock = productGroupStock - oldStock + newStock;
                LambdaUpdateWrapper<StoreProductAttrValue> updateWrapper = new LambdaUpdateWrapper();
                updateWrapper.eq(StoreProductAttrValue::getId, attrValue.getId());
                updateWrapper.set(StoreProductAttrValue::getStock, stock);
                updateWrapper.set(StoreProductAttrValue::getGroupStock, productGroupStock);
                storeProductAttrValueService.update(updateWrapper);

            }
        }

    }

    /**
     * 校验商品的拼团库存量是否超过商品库存量
     *
     * @param request
     */
    @Override
    public void checkStock(ChannelGroupBookingRequest request) {
        Integer productId = request.getProductId();
        // 获取商品规格
        List<StoreProductAttrValue> attrValueList = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .eq(StoreProductAttrValue::getProductId, productId)
        );
        if (CollectionUtils.isEmpty(attrValueList)) {
            throw new CrmebException("拼团对应的商品为空，数据异常");
        }
        // map
        Map<String, StoreProductAttrValue> attrValueMap = attrValueList.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, e -> e, (v1, v2) -> v2));

        //拼团人数与拼团价对应关系
        List<ChannelGroupBookingRequest.StoreProductGroupActivityRequest> storeProductGroupActivities = request.getStoreProductGroupActivities();
        for (ChannelGroupBookingRequest.StoreProductGroupActivityRequest activityRequest : storeProductGroupActivities) {
            for (ChannelGroupBookingRequest.StoreProductGroupActivityRequest.StoreProductGroupPriceRequest priceRequest : activityRequest.getSkuPrices()) {
                String sourceSkuId = priceRequest.getSourceSkuId();
                Integer groupStock = priceRequest.getStock();
//                if(null == groupStock || groupStock == 0){
//                    throw new CrmebException("拼团库存量不能为空！");
//                }
                if(null == sourceSkuId){
                    throw new CrmebException("商品规格不能为空！");
                }
                // 获取商品的库存量
                // 商品规格
                StoreProductAttrValue attrValue = attrValueMap.get(sourceSkuId);
                if(null == attrValue){
                    throw new CrmebException("商品规格为空，数值异常！");
                }
                // 商品库存量
                if(attrValue.getStock() == null){
                    attrValue.setStock(0);
                }
                if (attrValue.getStock() < groupStock) {
                    log.info("库存量：{}，{}，{}",attrValue.getStock(), groupStock);
                    throw new CrmebException("商品可用库存量不足，请修改参加拼团的库存量！");
                }

                // 锁库存
                Integer stock = attrValue.getStock() - groupStock;
                Integer productGroupStock = attrValue.getGroupStock() == null ? 0 : attrValue.getGroupStock();
                productGroupStock += groupStock;
                LambdaUpdateWrapper<StoreProductAttrValue> updateWrapper = new LambdaUpdateWrapper();
                updateWrapper.eq(StoreProductAttrValue::getId, attrValue.getId());
                updateWrapper.set(StoreProductAttrValue::getStock, stock);
                updateWrapper.set(StoreProductAttrValue::getGroupStock, productGroupStock);
                storeProductAttrValueService.update(updateWrapper);

            }
        }

    }

    /**
     * 修改商品时，归还原商品锁定的库存
     *
     */
    @Override
    public void returnStock(Integer productId, ChannelGroupBookingRequest request, List<Integer> activityIds) {
        if (CollectionUtils.isEmpty(activityIds)){
            return ;
        }
        String groupId = request.getGroupId();
        List<StoreProductGroupActivity> list = new ArrayList<>();
        if(StringUtils.isNotBlank(groupId)){
            list = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .eq(StoreProductGroupActivity::getProductId, productId)
                    .eq(StoreProductGroupActivity::getGroupId, groupId));
        }else {
            list = storeProductGroupActivityService.list(Wrappers.<StoreProductGroupActivity>lambdaQuery()
                    .eq(StoreProductGroupActivity::getProductId, productId)
                    .in(StoreProductGroupActivity::getActivityId, activityIds)
                    .isNull(StoreProductGroupActivity::getGroupId));
        }
        if(CollectionUtils.isEmpty(list)){
            throw new CrmebException("程序异常，怎么可以没有拼团原数据！");
        }
        // 获取商品规格
        List<StoreProductAttrValue> attrValueList = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .eq(StoreProductAttrValue::getProductId, productId)
        );
        if (CollectionUtils.isEmpty(attrValueList)) {
            log.info("拼团原商品对应的商品为空，不用返还库存");
            return;
        }
        // map
        Map<String, StoreProductAttrValue> attrValueMap = attrValueList.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, e -> e, (v1, v2) -> v2));

        for(StoreProductGroupActivity activity : list){
            Integer stock = activity.getStock();
            if (null == stock || 0 == stock) {
                continue;
            }
            String sourceSkuId = activity.getSourceSkuId();
            if(null == sourceSkuId){
                throw new CrmebException("商品规格id不能为空！");
            }
            StoreProductAttrValue attrValue = attrValueMap.get(sourceSkuId);
            if(null == attrValue){
                continue;
            }
            Integer newStock = attrValue.getStock() == null ? 0 : attrValue.getStock();
            Integer productGroupStock = attrValue.getGroupStock() == null ? 0 : attrValue.getGroupStock();
            newStock += stock;
            productGroupStock -= stock;
            if(productGroupStock < 0){
                productGroupStock = 0;
            }

            // 归还库存
            LambdaUpdateWrapper<StoreProductAttrValue> updateWrapper = new LambdaUpdateWrapper();
            updateWrapper.eq(StoreProductAttrValue::getId, attrValue.getId());
            updateWrapper.set(StoreProductAttrValue::getStock, newStock);
            updateWrapper.set(StoreProductAttrValue::getGroupStock, productGroupStock);
            storeProductAttrValueService.update(updateWrapper);

        }
        storeProductGroupActivityService.removeProductByProductIdAndGroupId(productId, groupId);

    }

}